package cz.vse.javaee.album;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;

@Stateless
@Local(AlbumDAO.class)
@Remote(AlbumDAORemote.class)
public class AlbumDAOBean implements AlbumDAO, AlbumDAORemote {
    public static final String PHOTO_BY_NAME = "PHOTO_BY_NAME";

    @PersistenceContext(unitName = "album")
    private EntityManager entityManager;

    @EJB
    private PhotoCacheRemote photoCache;

    @Override
    public List<Album> getAlbums() {
        Query query = entityManager.createQuery("select a from Album a");
        return query.getResultList();
    }

    @Override
    @Interceptors(CacheSynchronizer.class)
    public void addPhoto(Photo photo, String albumName) {
        Album album = entityManager.find(Album.class, albumName);
        if (album == null) {
            album = new Album();
            album.setName(albumName);
            album.setCreated(new Date());
            entityManager.persist(album);
        }

        album.getPhotos().add(photo);
        photo.setAlbum(album);

        entityManager.persist(photo);
        entityManager.flush();
        entityManager.refresh(photo);
    }

    @Override
    public List<Photo> getPhotos() {
        Query query = entityManager.createQuery("select p from Photo p");
        return query.getResultList();
    }

    @Override
    public Photo findPhoto(String photoName) throws NoPhotoFoundException {
        Query query = entityManager.createNamedQuery(PHOTO_BY_NAME);
        query.setParameter("name", photoName);
        try {
            Photo photo = (Photo) query.getSingleResult();
            photo.getImage();
            return photo;
        } catch (NoResultException e) {
            throw new NoPhotoFoundException(photoName);
        }
    }

    @Override
    public Photo findPhotoIcon(String photoName) throws NoPhotoFoundException {
        return photoCache.getIconByName(photoName);
    }

    @Override
    @Interceptors(CacheSynchronizer.class)
    public Photo updatePhoto(Photo photo) {
        return entityManager.merge(photo);
    }

    @Override
    @Interceptors(CacheSynchronizer.class)
    public void removePhotos(int[] selectedIds) {
//        for (int i = 0; i < selectedIds.length; i++) {
//            int selectedId = selectedIds[i];
//            Photo photo = entityManager.find(Photo.class, selectedId);
//            if (photo != null) {
//                entityManager.remove(photo);
//            }
//        }
        String seq = createDelimitedSequence(selectedIds);
        Query query = entityManager.createQuery("delete from Photo p where p.id in (" + seq + ")");
        query.executeUpdate();
    }

    private String createDelimitedSequence(int[] selectedIds) {
        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < selectedIds.length; j++) {
            int selectedId = selectedIds[j];
            if (j > 0) {
                sb.append(',');
            }
            sb.append(selectedId);
        }
        return sb.toString();
    }
}
